/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - core/math
// Copyright (c) 2014.  All Rights Reserved
//
// File:		AEEulerMode.h
// Author:		Gianluca Belardelli
// Date:		31/07/2013
// Purpose:		Dichiarazione della classe AEEulerMode
//
// Revision:
//				001 - 31/07/2013
//					+ Revisione iniziale
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AEEULERMODE_H_
#define _AEEULERMODE_H_

#define EulerOrder(I,P,R,F) (F) | (R << 1) | (P << 2) | (I << 3)

/// \brief
///   This is a helper class to convert Euler angles to and from matrices and quaternions.
///   It works with every mode known to man.
///   The code was taken from "Graphics Gems IV", "Euler Angle Conversion" by Ken Shoemake, page 222.
class AEEulerMode
{
public:
	/// \brief [internal]
	enum Frame      { Static = 0, Rotating = 1 };
	/// \brief [internal]
	enum Repetition { RepNo  = 0, RepYes   = 1 };
	/// \brief [internal]
	enum Parity     { Even   = 0, Odd      = 1 };
	/// \brief [internal]
	enum InnerAxis  { AxisX  = 0, AxisY    = 1, AxisZ  = 2 };

	/// \brief
	///   Defines all the different modes that euler angles could be used like.
	///
	/// 's' means 'static', ie. rotate around the GLOBAL axis.
	/// 'r' means 'rotating', ie. rotate around the LOCAL axis.
	///
	/// For example XYZs means:
	/// rotate around the global Z axis, then
	/// rotate around the global Y axis, then
	/// rotate around the global X axis
	///
	/// The Vision Engine uses 'XYZs' as its default mode (which is the same 3D Studio Max uses).
	/// Other classes like 'hkvQuat' use Euler Angles as 'Roll, Pitch, Yaw'. Since XYZs is then used,
	/// this translates to 'Roll' == 'X Axis', Pitch == 'Y Axis', 'Yaw' == 'Z Axis'
	enum Enum
	{
		XYZs = EulerOrder( AxisX, Even, RepNo , Static ),
		XYXs = EulerOrder( AxisX, Even, RepYes, Static ),
		XZYs = EulerOrder( AxisX,  Odd, RepNo , Static ),
		XZXs = EulerOrder( AxisX,  Odd, RepYes, Static ),
		YZXs = EulerOrder( AxisY, Even, RepNo , Static ),
		YZYs = EulerOrder( AxisY, Even, RepYes, Static ),
		YXZs = EulerOrder( AxisY,  Odd, RepNo , Static ),
		YXYs = EulerOrder( AxisY,  Odd, RepYes, Static ),
		ZXYs = EulerOrder( AxisZ, Even, RepNo , Static ),
		ZXZs = EulerOrder( AxisZ, Even, RepYes, Static ),
		ZYXs = EulerOrder( AxisZ,  Odd, RepNo , Static ),
		ZYZs = EulerOrder( AxisZ,  Odd, RepYes, Static ),
		ZYXr = EulerOrder( AxisX, Even, RepNo , Rotating ),
		XYXr = EulerOrder( AxisX, Even, RepYes, Rotating ),
		YZXr = EulerOrder( AxisX,  Odd, RepNo , Rotating ),
		XZXr = EulerOrder( AxisX,  Odd, RepYes, Rotating ),
		XZYr = EulerOrder( AxisY, Even, RepNo , Rotating ),
		YZYr = EulerOrder( AxisY, Even, RepYes, Rotating ),
		ZXYr = EulerOrder( AxisY,  Odd, RepNo , Rotating ),
		YXYr = EulerOrder( AxisY,  Odd, RepYes, Rotating ),
		YXZr = EulerOrder( AxisZ, Even, RepNo , Rotating ),
		ZXZr = EulerOrder( AxisZ, Even, RepYes, Rotating ),
		XYZr = EulerOrder( AxisZ,  Odd, RepNo , Rotating ),
		ZYZr = EulerOrder( AxisZ,  Odd, RepYes, Rotating ),
		AEEngineDefault = XYZs
	};
};

#endif
// _AEEULERMODE_H_
